import requests
import re
import json
from frame_work.setting import *
from frame_work.yaml_file import YAML
from frame_work.logger import Logger
from frame_work.type_file import Card

logger = Logger(__name__).get_logger()


class Login(object):

    def __init__(self, uname=None):
        self.uname = uname
        self.session = requests.session()
        self.yaml = YAML(os.path.join(base_Dir, 'data', 'data.yaml'))
        # self.logger = Logger(logger="login").get_logger()

    def get_login_data(self, *args, **kwargs):
        """
        用户登录的数据参数，包括login_url,postData,headers
        :param args:
        :param kwargs:
        :return:
        """
        yaml_data = self.yaml.get_data(kwargs.get('who'))
        try:
            card1 = args[0]
            card2 = args[1]
            card_value = args[2]
        except IndexError as e:
            card1 = card2 = card_value = None
        if all((card1, card2, card_value)):
            yaml_data.get('data').update({
                'security_1': card1,
                'security_2': card2,
                'card': card_value
            })
            # post_data = self.public.post_data(kwargs.get('p_index'),card1=card1,card2=card2,card_value=card_value,name=self.uname)
        else:
            # post_data = self.public.post_data(kwargs.get('p_index'),name=self.uname)
            if self.uname:
                if kwargs.get('flag') == 1:
                    yaml_data.get('data').update({
                        'uname': self.uname
                    })
                else:
                    yaml_data.get('data').update({
                        'username': self.uname
                    })
        return yaml_data.get('url'), yaml_data.get(
            'data'), yaml_data.get('header')

    @staticmethod
    def _success_log(f):
        """
        父类装饰器，提供子类login登陆成功日志打印功能
        :return:
        """
        def wrapper(*args, **kwargs):
            res = f(*args, **kwargs)
            res_t = json.loads(res.text)
            if res_t.get('success') or res_t.get('code') == 'OK':
                logger.debug("登录成功...")
            else:
                logger.debug("登录失败...")
            return res
        return wrapper

    def get_session(self):
        """
        登录成功，返回一个session实例
        :return:
        """
        return self.session


class PcLogin(Login):

    def __init__(self, uname):
        #super(otherclass, self).__init__()
        Login.__init__(self, uname)

    @Login._success_log
    def pc_login(self):
        """
        PC用户登录
        :return:
        """
        logger.debug("执行联盟PC端用户< %s >登录操作..." % self.uname)
        # PC用户登录的数据，包括pc_login_url,postData,header
        url, postData, header = self.get_login_data(who="seller_login")
        response = self.session.post(url, data=postData, headers=header)
        return response

    @Login._success_log
    def tfx_pc_login(self):
        """
        淘发现PC用户登录
        :return:
        """
        logger.debug("执行淘发现PC端用户< %s >登录操作..." % self.uname)
        # PC用户登录的数据，包括pc_login_url,postData,header
        url, postData, header = self.get_login_data(who="tfx_login")
        response = self.session.post(url, data=postData, headers=header)
        return response


class SystemLogin(Login):

    def __init__(self):
        Login.__init__(self)

    @Login._success_log
    def sksystem_login(self):
        """
        system登录
        :return:
        """
        logger.debug("执行system用户登录操作...")
        # system用户登录的数据，包括url,postData,header
        url, postData, header = self.get_login_data(who="system_login")
        response = self.session.post(url, data=postData, headers=header)
        return response


class AdminLogin(Login):

    def __init__(self):
        Login.__init__(self)

    def admin_login(self):
        """
        管理员登录
        :return:
        """
        logger.debug("进行管理员admin用户登录操作...")
        # admin登录的数据，包括admin_login_url,postData,header
        url, postData, header = self.get_login_data(who="admin_login")
        response = self.session.post(url, data=postData, headers=header)
        return response

    def admin_login_success(self):
        """
        admin管理员登录后，并跳转到验证口令页面
        :return:
        """
        response = self.admin_login()
        if 'true' in response.text:
            logger.debug("管理员登录成功，现在进行口令的验证...")
            yaml_data = self.yaml.get_data('admin_login_success')
            response_text = self.session.get(yaml_data.get('url')).text
            return response_text

    @Login._success_log
    def admin_card_login(self):
        """
        admin管理员登录且验证口令成功后正式登陆成功。
        :return:
        """
        response_text = self.admin_login_success()
        card1, card2 = AdminLogin.get_cards(response_text)
        card1, card2, card_value = self.get_card_result_value(card1, card2)
        logger.debug("执行管理员admin用户口令登录操作...")
        # admin验证口令登录的数据，包括admin_login_url,postData,header
        url, postData, header = self.get_login_data(
            who="admin_card_login", *(card1, card2, card_value))
        response = self.session.post(url, data=postData, headers=header)
        return response

    @staticmethod
    def get_cards(val):
        """
        管理员登录响应HTML中正则提取两个口令值
        :param val:
        :return:
        """
        comp = 'value="(.*?)"'
        value = re.findall(comp, val)  # 正则表达式截取口令值
        card1 = value[0]
        card2 = value[1]
        return card1, card2

    def get_card_result_value(self, card1, card2):
        """
        取联盟数据库sk_user_security_card表中管理员的口令比对值,管理员一般是固定值
        :param card1:
        :param card2:
        :return:
        """
        card_equal_value = Card.card.value
        key_1 = card1[0]
        index_1 = card1[1]
        key_2 = card2[0]
        index_2 = card2[1]
        value_1 = card_equal_value.get(key_1)[int(index_1)]
        value_2 = card_equal_value.get(key_2)[int(index_2)]
        card_value = str(value_1) + str(value_2)
        return card1, card2, card_value


class AppLogin(Login):

    def __init__(self, uname):
        Login.__init__(self, uname)
        self.sign = ''

    @Login._success_log
    def app_login(self):
        """
        app登录操作
        :return:
        """
        logger.debug("执行APP端用户< %s >登录操作..." % self.uname)
        # APP用户登录的数据，包括login_url,postData,header
        url, postData, header = self.get_login_data(who="app_login", flag=1)
        response = self.session.post(url, data=postData, headers=header)
        return response

    def appget_sign(self):
        """
        提取登录成功返回的凭证sign数据
        :return:
        """
        res = self.app_login()
        res_t = json.loads(res.text)
        if res_t.get('code') == 'OK':
            # self.sign = re.findall(r'"sign":"(.*?)"',res_t)[0]
            self.sign = res_t.get('data').get('sign')
            return self.sign
        return


class TfxAdminLogin(Login):

    def __init__(self):
        Login.__init__(self)

    def tfx_admin_login(self):
        """
        tfx 管理员登录
        :return:
        """
        logger.debug("进行tfx管理员admin用户登录操作...")
        # admin登录的数据，包括admin_login_url,postData,header
        url, postData, header = self.get_login_data(who="tfx_admin_login")
        response = self.session.post(url, data=postData, headers=header)
        return response

    def tfx_admin_login_success(self):
        """
        tfx admin管理员登录后，并跳转到验证口令页面
        :return:
        """
        response = self.tfx_admin_login()
        if 'true' in response.text:
            logger.debug("tfx管理员登录成功，现在进行口令的验证...")
            yaml_data = self.yaml.get_data('tfx_admin_login_success')
            response_text = self.session.get(yaml_data.get('url')).text
            return response_text

    @Login._success_log
    def tfx_admin_card_login(self):
        """
        tfx admin管理员登录且验证口令成功后正式登陆成功。
        :return:
        """
        response_text = self.tfx_admin_login_success()
        card1, card2 = TfxAdminLogin.get_cards(response_text)
        card1, card2, card_value = self.get_card_result_value(card1, card2)
        logger.debug("执行tfx管理员admin用户口令登录操作...")
        # admin验证口令登录的数据，包括admin_login_url,postData,header
        url, postData, header = self.get_login_data(
            who="tfx_admin_card_login", *(card1, card2, card_value))
        response = self.session.post(url, data=postData, headers=header)
        return response

    @staticmethod
    def get_cards(val):
        """
        管理员登录响应HTML中正则提取两个口令值
        :param val:
        :return:
        """
        comp = 'value="(.*?)"'
        value = re.findall(comp, val)  # 正则表达式截取口令值
        card1 = value[0]
        card2 = value[1]
        return card1, card2

    def get_card_result_value(self, card1, card2):
        """
        取联盟数据库sk_user_security_card表中管理员的口令比对值,管理员一般是固定值
        :param card1:
        :param card2:
        :return:
        """
        card_equal_value = Card.card.value
        key_1 = card1[0]
        index_1 = card1[1]
        key_2 = card2[0]
        index_2 = card2[1]
        value_1 = card_equal_value.get(key_1)[int(index_1)]
        value_2 = card_equal_value.get(key_2)[int(index_2)]
        card_value = str(value_1) + str(value_2)
        return card1, card2, card_value


class TfxSystemLogin(Login):

    def __init__(self):
        Login.__init__(self)

    @Login._success_log
    def tfx_system_login(self):
        """
        tfx system登录
        :return:
        """
        logger.debug("执行tfx system用户登录操作...")
        # system用户登录的数据，包括system_login_utl,postData,header
        url, postData, header = self.get_login_data(who="tfx_system_login")
        response = self.session.post(url, data=postData, headers=header)
        return response


if __name__ == "__main__":
    # login= PcLogin('user157')
    # print(login.pc_login().text)
    # login = AppLogin('user147')
    # login.appget_sign()
    # print(login.appget_sign())

    admin_login = AdminLogin()
    admin_login.admin_card_login()
    # print(admin_login.admin_card_login().text)
    # admin_session = admin_login.get_session()
    # login = TfxSystemLogin()
    # print(login.tfx_system_login().text)
